package com.bt.lms.ui.page.sys.role;

import com.alibaba.fastjson.JSONObject;
import com.bt.lms.entity.Role;
import com.bt.lms.entity.page.Page;
import com.bt.lms.ui.page.common.PageLocation;
import com.bt.lms.ui.page.common.PagePaging;
import com.bt.lms.main.BotLmsApp;
import com.bt.lms.ui.page.sys.page.paging.PagePagingQuery;
import com.bt.lms.ui.page.sys.role.action.*;
import com.bt.lms.ui.page.sys.style.BtnStyle;
import com.bt.lms.ui.page.sys.utils.MyButton;
import com.bt.lms.ui.page.sys.utils.MyVBox;
import com.bt.lms.ui.page.sys.vo.RoleTableViewVo;
import com.bt.lms.ui.vo.PageSkipInfo;
import com.bt.lms.ui.page.sys.vo.RoleInfoVo;
import javafx.collections.FXCollections;
import javafx.collections.ObservableList;
import javafx.geometry.Insets;
import javafx.scene.Node;
import javafx.scene.control.*;
import javafx.scene.control.cell.PropertyValueFactory;
import javafx.scene.layout.HBox;
import javafx.scene.layout.VBox;
import javafx.util.Callback;
import org.apache.commons.beanutils.BeanUtils;

import java.lang.reflect.InvocationTargetException;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.List;

/**
 * 角色列表界面
 */
public class PageList extends VBox {

    /**
     * 界面跳转数据
     */
    private final PageSkipInfo pageSkipInfo;

    /**
     * 分页模型
     */
    private Page<Role> page;

    /**
     * 列表区
     */
    private MyVBox listVBox;


    /**
     * 构建角色列表界面
     *
     * @param pageSkipInfo 此界面的一些数据（所在容器 + 所在容器中的角标）
     */
    @Deprecated
    public PageList(PageSkipInfo pageSkipInfo) {

        //自己可能用的东东西
        this.setId("PageList");
        this.pageSkipInfo = pageSkipInfo;

        //大小a
        this.setPrefWidth(BotLmsApp.PER_WIGHT);
        this.setPrefHeight(BotLmsApp.HEIGHT);

        //布局
        Insets insets = new Insets(0);
        this.setPadding(insets);

        //组件
        //定位区域
        PageLocation pageLocation = new PageLocation("系统管理", "角色权限管理");
        this.getChildren().add(pageLocation);

        //列表区域
        MyVBox listVBox = new MyVBox();
        listVBoxInit(listVBox);
        this.getChildren().add(listVBox);

        //搜索区域
        PagePaging pagePaging = new PagePaging();
        this.getChildren().add(pagePaging);

    }

    /**
     * 构建角色列表界面
     *
     * @param pageSkipInfo 界面跳转信息
     * @param page    分页模型（）
     */
    public PageList(PageSkipInfo pageSkipInfo, Page<Role> page) {
        //自己可能用的东东西
        this.setId("PageList");
        this.pageSkipInfo = pageSkipInfo;
        this.page = page;

        //大小
        this.setPrefWidth(BotLmsApp.PER_WIGHT);
        this.setPrefHeight(BotLmsApp.HEIGHT);

        //布局
        Insets insets = new Insets(0);
        this.setPadding(insets);

        //组件
        //定位区域
        PageLocation pageLocation = new PageLocation("系统管理", "角色权限管理");
        this.getChildren().add(pageLocation);

        //列表区域
        listVBox = new MyVBox();
        operateBtnInit(listVBox);
        RoleTableView roleTableView = new RoleTableView(listVBox, page, pageSkipInfo);
        listVBox.getChildren().add(roleTableView);
        this.getChildren().add(listVBox);

        //搜索区域
        PagePagingQuery<Role> rolePagePagingQuery = new PagePagingQuery<>(pageSkipInfo, page, Role.class);
        this.getChildren().add(rolePagePagingQuery);

    }

    /**
     * 列表区域初始化
     *
     * @param listVBox 列表区域
     */
    private void listVBoxInit(MyVBox listVBox) {



        //列表
        //1.建立列表视图
        TableView<RoleInfoVo> tableView = new TableView<>();

        //准备数据
        //1 数据初始化
        List<RoleInfoVo> roleInfoVos = dataInit();
        //2 格式转化(用户数据集合转换成Javafx组件集合)
        ObservableList<RoleInfoVo> users = FXCollections.observableArrayList(roleInfoVos);
        //3 数据添加到表格
        tableView.setItems(users);

        //新建列头
        TableColumn<RoleInfoVo, String> codeTC = new TableColumn<>("角色编码");
        TableColumn<RoleInfoVo, String> nameTC = new TableColumn<>("角色名称");
        TableColumn<RoleInfoVo, String> builderTC = new TableColumn<>("创建人");
        TableColumn<RoleInfoVo, LocalDateTime> buildTimeTC = new TableColumn<>("创建时间");
        TableColumn<RoleInfoVo, LocalDateTime> alterTimeTC = new TableColumn<>("最近变更时间");
        TableColumn<RoleInfoVo, RoleTableViewVo> operateTC = new TableColumn<>("操作");

        //列头添加到视图
        tableView.getColumns().addAll(codeTC, nameTC, builderTC, buildTimeTC, alterTimeTC, operateTC);

        //映射（让每一列知道要展示的属性是哪一个）
        codeTC.setCellValueFactory(new PropertyValueFactory<>("code"));
        nameTC.setCellValueFactory(new PropertyValueFactory<>("name"));
        builderTC.setCellValueFactory(new PropertyValueFactory<>("builder"));
        buildTimeTC.setCellValueFactory(new PropertyValueFactory<>("buildTime"));
        alterTimeTC.setCellValueFactory(new PropertyValueFactory<>("alterTime"));
        operateTC.setCellValueFactory(new PropertyValueFactory<>("roleTableViewVo"));

        //试图添加
        ObservableList<Node> tableChildren = listVBox.getChildren();
        tableChildren.add(tableView);

        //自定义界面渲染
        customVRay(buildTimeTC, operateTC);

    }

    /**
     * 列表区域的操作按钮初始化
     *
     * @param listVBox 列表盒子
     */
    private void operateBtnInit(MyVBox listVBox) {

        //组件(操作按钮)
        MyButton addRoleBtn = new MyButton("新增角色");
        //事件
        RLAddRoleBtnAction RLAddRoleBtnAction = new RLAddRoleBtnAction(pageSkipInfo);
        addRoleBtn.setOnAction(RLAddRoleBtnAction);
        //样式 + 样式事件
        BtnStyle.addBtn(addRoleBtn);
        BtnStyle.addBtnAction(addRoleBtn);

        //按钮内部布局
        Insets addUserBtnInsets = new Insets(5, 12, 5, 12);
        addRoleBtn.setPadding(addUserBtnInsets);
        //操作按钮盒子（让操作按钮有间隔）
        HBox addUserBtnBox = new HBox();
        //操作按钮盒子布局
        Insets addUserBtnBoxInsets = new Insets(10);
        addUserBtnBox.setPadding(addUserBtnBoxInsets);
        //盒子内添加按钮
        addUserBtnBox.getChildren().add(addRoleBtn);
        //添加到列表容器
        ObservableList<Node> addUserChildren = listVBox.getChildren();
        addUserChildren.add(addUserBtnBox);
    }

    /**
     * 数据初始化
     *
     * @return 模拟好的数据集合
     */
    private List<RoleInfoVo> dataInit() {

        //数据总集合
        List<RoleInfoVo> roleInfoVos = new ArrayList<>();

        List<Role> records = page.getRecords();

        for (Object record : records) {
            //解JSON
            JSONObject roleJSON = (JSONObject) record;
            Role javaObject = roleJSON.toJavaObject(Role.class);
            RoleInfoVo roleInfoVo = new RoleInfoVo();
            try {
                BeanUtils.copyProperties(roleInfoVo, javaObject);
                //对象维护 用户操作视图对象
                RoleTableViewVo roleTableViewVo = new RoleTableViewVo();
                BeanUtils.copyProperties(roleTableViewVo, roleInfoVo);
                roleInfoVo.setRoleTableViewVo(roleTableViewVo);

            } catch (IllegalAccessException | InvocationTargetException e) {
                throw new RuntimeException(e);
            }
            roleInfoVos.add(roleInfoVo);
        }


        //返回全部数据
        return roleInfoVos;
    }

    /**
     * 操作按钮盒子初始化
     *
     * @param roleTableViewVo 角色编号
     * @return 操作按钮盒子
     */
    private HBox operateHBoxInit(RoleTableViewVo roleTableViewVo) {

        //新建操作盒子
        HBox operateHBox = new HBox();
        operateHBox.setPadding(new Insets(2));
        operateHBox.setSpacing(10);

        //操作按钮(查看权限
        MyButton checkMajorBtn = new MyButton("查看权限");
        operateHBox.getChildren().add(checkMajorBtn);

        //操作按钮(设置权限
        MyButton setMajorBtn = new MyButton("设置权限");
        operateHBox.getChildren().add(setMajorBtn);

        //操作按钮(查看用户
        MyButton checkUserBtn = new MyButton("查看用户");
        operateHBox.getChildren().add(checkUserBtn);

        //操作按钮(添加用户
        MyButton addUserBtn = new MyButton("添加用户");
        operateHBox.getChildren().add(addUserBtn);
        //事件
        RLAddUserBtnAction rlAddUserBtnAction = new RLAddUserBtnAction(roleTableViewVo, pageSkipInfo);
        addUserBtn.setOnAction(rlAddUserBtnAction);

        //操作按钮(编辑角色
        MyButton redactBtn = new MyButton("编辑角色");
        operateHBox.getChildren().add(redactBtn);
        //事件
        RLCompileRoleBtnAction RLCompileRoleBtnAction = new RLCompileRoleBtnAction(roleTableViewVo, pageSkipInfo);
        redactBtn.setOnAction(RLCompileRoleBtnAction);

        //操作按钮(删除角色
        MyButton deleteBtn = new MyButton("删除角色");
        operateHBox.getChildren().add(deleteBtn);
        deleteBtn.setOnAction(new RLDeleteBtnAction(roleTableViewVo,pageSkipInfo,listVBox));

        return operateHBox;
    }

    /**
     * 自定义界面渲染
     *
     * @param buildTimeTC 创建时间列
     * @param operateTC   操作列
     */
    private void customVRay(TableColumn<RoleInfoVo, LocalDateTime> buildTimeTC
            , TableColumn<RoleInfoVo, RoleTableViewVo> operateTC) {

        //创建时间列自定义
        buildTimeTC.setCellFactory(new Callback<TableColumn<RoleInfoVo, LocalDateTime>, TableCell<RoleInfoVo, LocalDateTime>>() {
            @Override
            public TableCell<RoleInfoVo, LocalDateTime> call(TableColumn<RoleInfoVo, LocalDateTime> param) {
                return new TableCell<RoleInfoVo, LocalDateTime>() {
                    @Override
                    protected void updateItem(LocalDateTime buildTimeLDT, boolean empty) {
                        //覆盖TableCell的样式更新
                        super.updateItem(buildTimeLDT, empty);
                        if (buildTimeLDT != null) {
                            LocalDate buildTimeLD = buildTimeLDT.toLocalDate();
                            String buildTimeStr = buildTimeLD.toString();
                            Label buildTimeLab = new Label(buildTimeStr);
                            setGraphic(buildTimeLab);//界面显示
                        }
                    }
                };
            }
        });

        //操作列自定义
        operateTC.setCellFactory(new Callback<TableColumn<RoleInfoVo, RoleTableViewVo>, TableCell<RoleInfoVo, RoleTableViewVo>>() {
            @Override
            public TableCell<RoleInfoVo, RoleTableViewVo> call(TableColumn<RoleInfoVo, RoleTableViewVo> param) {
                return new TableCell<RoleInfoVo, RoleTableViewVo>() {
                    @Override
                    protected void updateItem(RoleTableViewVo roleTableViewVo, boolean empty) {
                        //覆盖TableCell的样式更新
                        super.updateItem(roleTableViewVo, empty);
                        if (roleTableViewVo != null) {
                            HBox hBox = operateHBoxInit(roleTableViewVo);
                            setGraphic(hBox);//界面显示
                        }
                    }
                };
            }
        });

    }
}